package jwt

import (
	"batbat-backend/app/model"
	"github.com/dgrijalva/jwt-go"
	"github.com/gogf/gf/frame/g"
	"time"
)

const HeaderKey = "Authorization" // token存放在请求头中的key

var (
	// 在配置文件中${jwt.signature}项以设置签名, 这里直接获取[]byte类型方便加密
	signature = g.Config().GetBytes("jwt.signature")
	// 在配置文件中${jwt.expiration}项以配置过期时长, 单位为秒
	expirationTime = time.Second * g.Config().GetDuration("jwt.expiration")
)

// userClaims 用户载体, 继承用户上下文以及jwt.StandardClaims类型
type userClaims struct {
	*model.UserContext
	jwt.StandardClaims
}

// Generate 根据用户上下文生成一个token
func Generate(user *model.UserContext) (string, error) {
	// 计算过期时间
	expireAt := time.Now().Add(expirationTime)
	// 将用户上下文以及过期时间写入token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, userClaims{
		UserContext: user,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expireAt.Unix(),
		},
	})
	// 对token进行签名
	return token.SignedString(signature)
}

// Verify 校验token并返回校验结果
func Verify(token string) (*model.UserContext, error) {
	// 新建载体用于接收结果
	claims := new(userClaims)
	// 解析传入的token
	_, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
		return signature, nil
	})
	if err != nil {
		return nil, err
	}
	return claims.UserContext, nil
}
